# 编写自己的函数
# R的优点之一就是用户可以自行添加函数
# 良好的编程习惯，是将一个800行的口水程序，改成一个个子函数
# 创造一个函数，其对象只在函数内部使用，返回值可以自由设定（标量、列表均可）
#
# Yuehan Yang. 2014/9/9 yyh@cufe.edu.cn

# 首先给出模板
# FNAME <- function ( ARG1, ARG2, ETC )
# {  
#   STATEMENT1 
#   STATEMENT2 
#   ETC 
#   return( VALUE ) 
# }
# 首先给出函数名（自定义）
# 其次是函数中需要的自变量列表
# { 包含你的函数所需要的命令语句 }
# return 返回你的函数输出
#

#
# e.g.1 数量成长函数（绘图）
ricker <- function(nzero, r, K=1, time=100, from=0, to=time){
  N <- numeric(time+1) # 赋值空向量
  N[1] <- nzero # 更改初始值
  for (i in 1:time) N[i+1] <- N[i]*exp(r*(1 - N[i]/K))
  # 该迭代模型广泛应用于数量变化（e.g.鱼类种群数量变化）
  # r 为成长率；nzero 为初始群体数量
  Time <- 0:time # 迭代步长
  plot(Time, N, type="l", xlim=c(from, to))
}
#
# 这是一个简单的画图函数 
# 按照喜好命名为 ricker
# 它的主要自变量是 nzero 与 r，其他变量都有缺省值
# 我们在使用它之前，首先需要载入内存
#
layout(matrix(1:3, 3, 1))
ricker(1, 1); title("r = 1")
ricker(0.1, 2); title("r = 2")
ricker(0.1, 3); title("r = 3")


# e.g.2 描述性统计量计算函数
# 函数要求：
# 1. 该函数用于计算数据对象的集中趋势和散布情况
# 2. 选择性地给出参数统计量（均值和标准差）
#      和非参数统计量（中位数和绝对中位差）
# 3. 结果以一个含名称列表的形式给出
# 4. 函数默认计算统计量并且不输出结果
mystats <- function(x,parametric = T, print = F){
  if (parametric) {
    center <- mean(x); spread <- sd(x)
  } else {
    center <- median(x); spread <- mad(x)
  }
  if (print & parametric) {
    cat("Mean=", center, "\n", "SD=", spread, "\n")
  } else if (print & !parametric){
    cat("Median=", center, "\n", "MAD=", spread, "\n")   
  }
  result <- list(center=center, spread=spread)
  return(result)
}
#
# 数据实践
x <- rnorm(500)
y <- mystats(x)
attributes(y)
# 包含均值 y$center, 标准差 y$spread
y <- mystats(x, parametric =F, print = T)

